import pandas as pd
from joblib import Parallel, delayed
from sklearn.feature_extraction.text import HashingVectorizer
from tqdm import tqdm


def handle_version(x, max_len=4):
    items = str(x).split('.')
    nums = [int(i) if i.isdigit() else 0 for i in items[:max_len]]
    return nums + [0] * (max_len - len(nums))


def fill_str_with_blank(df, str_cols):
    tqdm.pandas()
    for col in str_cols:
        df[col] = df[col].fillna('blank').progress_apply(str)
    return df


vect = HashingVectorizer(
    n_features=10,
    analyzer='char_wb',
    ngram_range=(3, 5),
    alternate_sign=False,
    norm='l2',
    lowercase=True
)


def text_to_vec(text):
    return vect.transform([str(text)]).toarray().flatten().tolist()


'''
    with ProcessPoolExecutor() as executor:
        futures = [
            executor.submit(process_col, df[col], col, i, len(str_array))
            for i, col in enumerate(str_array)
        ]
        dfs = [future.result() for future in futures]
'''


def process_str(series, col, i, all):
    print(f"[预处理]文本字段 {i + 1}/{all} {col} ")
    idf_max_features = 10
    vec_series = series.apply(text_to_vec)
    return pd.DataFrame(vec_series.tolist(), columns=[f'{col}_{i}' for i in range(idf_max_features)])


# def process_str(series, col, i, all):
#     print(f"[预处理]文本字段 {i + 1}/{all} {col} ")
#     idf_max_features = 10
#
#     vec_list = Parallel(n_jobs=-1)(
#         delayed(text_to_vec)(text) for text in series
#     )
#
#     return pd.DataFrame(vec_list, columns=[f'{col}_{i}' for i in range(idf_max_features)])


# def pre_handle_str_v2(df, columns):
#     print(f"[预处理]填充空文本")
#     df = fill_str_with_blank(df, columns)
#     with ProcessPoolExecutor() as executor:
#         futures = [
#             executor.submit(process_str, df[col], col, i, len(columns))
#             for i, col in enumerate(columns)
#         ]
#         dfs = [future.result() for future in futures]
#     df = pd.concat([df.reset_index(drop=True), *dfs], axis=1)
#     df.drop(columns=columns, inplace=True)
#     return df


def pre_handle_str_v2(df, columns):
    print(f"[预处理]填充空文本")
    df = fill_str_with_blank(df, columns)

    dfs = Parallel(n_jobs=-1)(
        delayed(process_str)(df[col], col, i, len(columns))
        for i, col in enumerate(columns)
    )

    df = pd.concat([df.reset_index(drop=True), *dfs], axis=1)
    df.drop(columns=columns, inplace=True)
    return df
